package com.gzdh.dishrecognition.ui.view;

import static com.blankj.utilcode.util.ViewUtils.runOnUiThread;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.graphics.drawable.GradientDrawable;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentManager;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.dhkj.web.idf.IdfRequestUtils;
import com.dhkj.web.idf.model.DishInfo;
import com.dhkj.web.idf.model.IDFWraper;
import com.dhkj.web.idf.model.MatchInfo;
import com.dhkj.web.idf.model.MatchLocation;
import com.dhkj.web.idf.model.MenuPicture;
import com.dhkj.web.idf.model.PictureSize;
import com.dhkj.web.idf.model.QueryWraper;
import com.dhkj.web.idf.model.RecognizeSet;
import com.dhkj.web.utils.MyObserverNo;
import com.dhkj.web.utils.MyObserverRes;
import com.dhkj.web.utils.RequestUtils;
import com.gzdh.dishrecognition.R;
import com.gzdh.dishrecognition.config.IdfConst;
import com.gzdh.dishrecognition.config.MyBaseConfig;
import com.gzdh.dishrecognition.config.SystemSettingObject;
import com.gzdh.dishrecognition.ui.activity.idf.FuHeActivity;
import com.gzdh.dishrecognition.util.CameraDataCallback;
import com.gzdh.dishrecognition.util.CameraPreviewManager;
import com.gzdh.dishrecognition.util.SharedPrefUtils;
import com.jiebao.led.uartled.UartLedController;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class IdfModelView extends LinearLayout {

    private static final String TAG = "IdfModelView";
    private Context mContext;
    private CameraPreviewManager cameraPreviewManager;

    AutoFitTextureView previewView;

    protected SystemSettingObject systemSettingObject;

    private boolean cameraInit;
    private int scale = 1;
    private Future future1;
    private int count;
    private ExecutorService es1 = Executors.newSingleThreadExecutor();

    public static final int CAMERA_OK = 10000;
    //餐盘进入
    private boolean dishIn;

    //餐盘大图识别发送
    private boolean dishInSend;

    private boolean connected;
    boolean manul;
    private WebSocket mWebSocket;
    private OkHttpClient mClient;
    protected Handler handler = new Handler();
    private Runnable restartRunnable;

    private ImageView rander_imageview;

    private RelativeLayout rander_layout;

    ExecutorService executorService = Executors.newSingleThreadExecutor();

    private ImageView connectStatusImg;
    private TextView connectStatusTips;

    public IdfModelView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.view_model_idf, this, true);
        mContext = context;
        systemSettingObject = (SystemSettingObject) SharedPrefUtils.getSerializableEntity("System_Setting");

        previewView = findViewById(R.id.my_textureview);
        rander_imageview = findViewById(R.id.rander_imageview);
        rander_layout = findViewById(R.id.rander_layout);
        connectStatusImg = findViewById(R.id.connectStatusImg);
        connectStatusTips = findViewById(R.id.connectStatusTips);
        UartLedController.sendBDisplayPkg((byte) 0x00, (byte) 0xFF, (byte) 0x00);
        cameraPreviewManager = CameraPreviewManager.getInstance();
        findViewById(R.id.paiCaiBut).setOnClickListener(view -> {
            FuHeActivity.start(mContext);
        });
        startBackgroundThread();

    }


    private HandlerThread mBackgroundThread;
    private Handler mBackgroundHandler;

    protected void startBackgroundThread() {
        mBackgroundThread = new HandlerThread("Camera Background");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
    }

    public void onStart() {
        restartWebSocket();
        initTools();
        mBackgroundHandler.post(() -> {
            initCamera();
            cameraPreviewManager.openCamera();
        });
    }

    private void initTools() {

    }
//     protected void onPause() {
//         //closeCamera();
//        releaseCamera();
//     }

    private void initCamera() {

        System.out.println("开始操作");
        cameraPreviewManager.startPreview(mContext, previewView, new CameraDataCallback() {
            @Override
            public void onOpened(int[] range) {
                cameraInit = true;
                System.out.println("开始预览");
//                runOnUiThread(() -> {
//                    idf_camera_no_tip.setVisibility(View.GONE);
//                    if (differentDislay != null && differentDislay.idf_camera_no_tip != null) {
//                        differentDislay.idf_camera_no_tip.setVisibility(View.GONE);
//                    }
//                });
                float middle = ((float) range[0] / 1000 + range[1] / 1000) / 2;
                scale = 1;
                if (middle > 5) {
                    BigDecimal b1 = new BigDecimal(middle);
                    BigDecimal b2 = new BigDecimal(5);
                    scale = b1.divide(b2, 0, BigDecimal.ROUND_UP).intValue();
                }
            }

            @Override
            public void onGetCameraData(byte[] data, Camera camera, int width, int height) {
                if (future1 != null && !future1.isDone()) {
                    return;
                }
                future1 = es1.submit(() -> {
                    final YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null);
                    ByteArrayOutputStream os = new ByteArrayOutputStream(data.length);
                    if (!image.compressToJpeg(new Rect(0, 0, width, height), 100, os)) {
                        return;
                    }
                    byte[] tmp = os.toByteArray();
                    count++;
                    if (count % scale == 0) {
                        count = 0;
                        runOnUiThread(() -> {
                            sendImageToServer(tmp);
                        });
                    }
//                    runOnUiThread(() -> {
//                        if (!differentStop && differentDislay != null) {
//                            Bitmap bmp = BitmapFactory.decodeByteArray(tmp, 0, tmp.length);
//                            if (differentDislay.previewView != null) {
//                                differentDislay.previewView.setImageBitmap(bmp);
//                            }
//                        }
//                    });

                });
            }
        });
    }

    public void send(final ByteString message) {

        if (mWebSocket != null) {
            executorService.submit(() -> {
                mWebSocket.send(message);
            });
        }
    }

    private void sendImageToServer(byte[] data) {
        if (manul) {
            sendBigRecognition(data);
            manul = false;

        }
        if (connected) {
            if (dishIn && !dishInSend) {
//                Log.e(TAG, "--------------data-size=" + data.length);
                dishInSend = true;
                //发送大图片识别
                sendBigRecognition(data);
            }
            Observable<byte[]> observable = Observable.create(emitter -> {
                emitter.onNext(data);
                emitter.onComplete();
            });
            observable.observeOn(Schedulers.io())
                    .map(o -> {
                        byte[] smallByte = convertScaledCompressJpeg(o, cameraPreviewManager.getPreviewWidth(), cameraPreviewManager.getPreviewHeight());
//                        Log.e(TAG, "map03:" + Thread.currentThread().getId());
                        return smallByte;
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(o -> {
                        send(new ByteString(o));
                        //            createDirSaveImage(data, previewSize);
//                        Log.e(TAG, "subscribe:" + Thread.currentThread().getId());
                    });
        }
    }

    public static byte[] convertScaledCompressJpeg(byte[] data, int width, int height) {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);//此时返回bm为空
        bitmap = bitmapRoom(bitmap, width / 4, height / 4, false);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos);
        bitmap.recycle();
        return baos.toByteArray();
    }

    /**
     * 将图片等比缩放到一定的区域
     *
     * @param srcBitmap
     * @param newWidth
     * @param newHeight
     * @param nagetive  true取大边false取小边
     * @return
     */
    public static Bitmap bitmapRoom(Bitmap srcBitmap, int newWidth, int newHeight, boolean nagetive) {
        int srcWidth = srcBitmap.getWidth();
        int srcHeight = srcBitmap.getHeight();
        float scaleWidth = ((float) newWidth) / srcWidth;
        float scaleHeight = ((float) newHeight) / srcHeight;
        boolean compare = scaleWidth < scaleHeight;
        compare = nagetive ? !compare : compare;
        scaleWidth = compare ? scaleWidth : scaleHeight;
        scaleHeight = compare ? scaleWidth : scaleHeight;
        Bitmap resizedBitmap = Bitmap.createScaledBitmap(srcBitmap, !compare ? (int) (srcWidth * scaleWidth) : newWidth,
                !compare ? newHeight : (int) (srcHeight * scaleHeight), true);
        if (resizedBitmap != null) {
            srcBitmap.recycle();
            return resizedBitmap;
        } else {
            return srcBitmap;
        }
    }


    private void restartWebSocket() {
        String urlString = IdfConst.getInstance().getIdfSystemUrl();
        if (urlString.contains("https")) {
            urlString = urlString.replace("https", "ws");
        }
        if (urlString.contains("http")) {
            urlString = urlString.replace("http", "ws");
        }
        String mWbSocketUrl = urlString + "/recognition/stream/judge_foreground/1";
        mClient = new OkHttpClient.Builder().pingInterval(10, TimeUnit.SECONDS).build();
        Request request = new Request.Builder().url(mWbSocketUrl).build();
        mWebSocket = mClient.newWebSocket(request, new WsListener());
    }

    class WsListener extends WebSocketListener {
        @Override
        public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
            super.onClosed(webSocket, code, reason);
            connected = false;
        }

        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @org.jetbrains.annotations.Nullable Response response) {
            super.onFailure(webSocket, t, response);
            Log.e(TAG, "websocket connect failed!");
//            httpLogger.timeFormatLog("websocket connect failed!");
            handler.post(() -> {
                if (connectStatusImg != null) {
//                    idf_connect_status.setImageResource(R.mipmap.idf_wifi_failed_beifen2);
                    connectStatusTips.setText("离线");
                    connectStatusTips.setTextColor(0xfffa5168);
                }
            });
            connected = false;
            restartRunnable = () -> restartWebSocket();
            handler.postDelayed(restartRunnable, 5000);
        }

        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
            super.onMessage(webSocket, text);
            Log.e(TAG, "-----------------客户端收到消息:" + text);
            try {
                JSONObject jsonObject = new JSONObject(text);
                //发送大图识别
                if (jsonObject.getInt("state") == 301) {
                    handler.postDelayed(() -> {
                        dishIn = true;
                        dishInSend = false;
//                        ToastUtils.toast(IDFActivity.this, "301");
                    }, 10);
                } else if (jsonObject.getInt("state") == 300) {
                    handler.post(() -> {
                        try {
                            startScan();
                            dishIn = false;
//                            boolean soundTips = systemSettingObject == null ? false : systemSettingObject.isSoundTips();
//                            if (soundTips && !billConsumed) {
//                                playMedia("no_pay.mp3");
//                            }
//                            if (continue_add) {
                            removeRander300();
//                            } else {
//                                removeRander();
//                            }
//                            ToastUtils.toast(IDFActivity.this, "300");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                } else if (jsonObject.getInt("state") == 304) {
                    handler.post(() -> {
                        try {
//                            if (continue_add) {
//                                removeRander300();
//                            } else {
//                                removeRander();
//                            }
                            dishIn = true;
                            dishInSend = false;
//                            ToastUtils.toast(IDFActivity.this, "304");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
            super.onOpen(webSocket, response);
            connected = true;
            Log.e(TAG, "连接成功！");
            handler.post(() -> {
                System.out.println("在线");
                if (connectStatusImg != null) {
//                    idf_connect_status.setImageResource(R.mipmap.idf_wifi_suc_beifen2);
                    connectStatusTips.setText("在线");
                    connectStatusTips.setTextColor(0xff316bee);
                    if (recognizeSet == null) {
                        query();
                    }
                }
            });
        }
    }

    private void query() {
        IdfRequestUtils.query(mContext, new MyObserverNo<QueryWraper>(mContext, false) {
            @Override
            public void onSuccess(QueryWraper result) {
                recognizeSet = result.getResult();
            }

            @Override
            public void onFailure(Throwable e, String errorMsg) {

            }
        });
    }

    private void startScan() {
        /*mQrLineView.setVisibility(View.VISIBLE);
        Translate m = new Translate(Translate.ABSOLUTE, 0f,
                Translate.ABSOLUTE, 0f, Translate.RELATIVE_TO_PARENT, 0f,
                Translate.RELATIVE_TO_PARENT, 0.9f);
        m.setDuration(1500);
        m.setRepeatCount(-1);
        m.setRepeatMode(.RESTART);
        m.setInterpolator(new LinearInterpolator());
        mQrLineView.set(m);*/
    }

    public void sendBigRecognition(byte[] data) {
        if (data == null) return;
        try {
//            logger.timeFormatLog("sendBigRecognition");
            Observable<byte[]> observable = Observable.create(emitter -> {
                createDirSaveImage(data);
                emitter.onNext(data);
                emitter.onComplete();
            });
            observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(o -> {
                        Log.e(TAG, "subscribe:" + Thread.currentThread().getId());
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
        Observable<byte[]> observable = Observable.create(emitter -> {
            Matrix m = new Matrix();
            boolean ox_reverse = false;
            boolean oy_reverse = false;
            m.postScale(ox_reverse ? -1 : 1, oy_reverse ? -1 : 1); // 镜像水平翻转
            Bitmap originBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);//此时返回bm为空
            if (originBitmap == null) return;
            Bitmap reverseBitmap = Bitmap.createBitmap(originBitmap, 0, 0, originBitmap.getWidth(), originBitmap.getHeight(), m, true);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            reverseBitmap.compress(Bitmap.CompressFormat.JPEG, systemSettingObject == null ? 70 : systemSettingObject.getCompress(), baos);
            originBitmap.recycle();
            reverseBitmap.recycle();
            emitter.onNext(baos.toByteArray());
            emitter.onComplete();
        });
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(o -> {
                    if (o == null) return;
                    IdfRequestUtils.bigRecognition(mContext, MyBaseConfig.getMyBaseConfig().getLibraryId(), o, new MyObserverNo<IDFWraper>(mContext, false) {
                        @Override
                        public void onSuccess(IDFWraper result) {
                            updateRender(result, o);
                        }

                        @Override
                        public void onFailure(Throwable e, String errorMsg) {

                        }
                    });
                    Log.e(TAG, "subscribe:" + Thread.currentThread().getId());
                });
    }


    public static void createDirSaveImage(byte[] data) {
        //保存一张照片
        String fileName = "IMG_" + System.currentTimeMillis() + ".jpg";  //jpeg文件名定义
        File sdRoot = Environment.getExternalStorageDirectory();    //系统路径
        String dir = "/jpeg/";   //文件夹名
        File mkDir = new File(sdRoot, dir);
        if (!mkDir.exists()) {
            mkDir.mkdirs();   //目录不存在，则创建
        }

        File pictureFile = new File(sdRoot, dir + fileName);
        if (!pictureFile.exists()) {
            saveByteToFile(data, pictureFile.getAbsolutePath());
//            saveByteToFile(convertScaledCompressJpeg(data, size.getWidth(),size.getHeight()), pictureFile.getAbsolutePath());
        }
    }

    public static void saveByteToFile(byte[] data, String path) {
        try {
            OutputStream out = new FileOutputStream(path);
            try {
                ByteArrayInputStream baio = new ByteArrayInputStream(data);
                byte[] buff = new byte[1024];
                int len;
                while ((len = baio.read(buff)) != -1) {
                    out.write(buff, 0, len);
                }
            } finally {
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    boolean bigRecognize;

    private void stopScan() {
        /*mQrLineView.setVisibility(View.GONE);
        mQrLineView.clear();*/
    }

    RequestOptions options = new RequestOptions()
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .priority(Priority.HIGH);

    private RecognizeSet recognizeSet;

    public void updateRender(IDFWraper idfWraper, byte[] data) {
        stopScan();
        bigRecognize = false;
        if (!cameraInit) return;
        if (idfWraper.getResults() == null) {
//            msgTip(idfWraper.getMessage(),2);
            return;
        }
        List<DishInfo> panDishInfos = idfWraper.getResults().getDishInfo();
        if (panDishInfos == null) {
            Toast.makeText(mContext, "未检测到菜品或未排菜", Toast.LENGTH_SHORT).show();

//            msgTip(idfWraper.getMessage() == null ? "未检测到菜品或未排菜！" : idfWraper.getMessage(),2);
            return;
        }
//        if (continue_add) {
        removeRander300();
//        } else {
//            removeRander();
//        }
//        continue_add = false;
        rander_imageview.setLayoutParams(previewView.getLayoutParams());
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) rander_layout.getLayoutParams();
        layoutParams.width = previewView.getRealWidth();
        layoutParams.height = previewView.getRealHeight();
        rander_layout.setLayoutParams(cameraInit ? layoutParams : previewView.getLayoutParams());
        rander_imageview.setVisibility(View.VISIBLE);
        rander_layout.setVisibility(View.VISIBLE);

        Glide.with(this)
                .asBitmap()
                .load(data/*.replace("192.168.1.160","10.10.0.6")*/)
                .apply(options)
                .skipMemoryCache(true) // 不使用内存缓存
                .diskCacheStrategy(DiskCacheStrategy.NONE) // 不使用磁盘缓存
                .into(rander_imageview);

        rander_layout.removeAllViews();

        int realWidth = previewView.getRealWidth();
        int realHeight = previewView.getRealHeight();

        int recognition_mode = recognizeSet == null ? 0 : recognizeSet.getRecognition_mode();
        Bitmap resource = BitmapFactory.decodeByteArray(data, 0, data.length);

        List<DishInfo> showDishInfos;
        if (recognition_mode == 3) {
            //region 混合识别
            showDishInfos = new ArrayList<>();
            List<DishInfo> panInfos = new ArrayList<>();
            List<DishInfo> dishInfos = new ArrayList<>();
            //返回的菜品遍历一遍
            for (DishInfo dishInfo : panDishInfos) {
                //取返回的第一个
                MatchInfo matchInfo = dishInfo.getMatchInfos().get(0);

                //盘ID
                if (!TextUtils.isEmpty(matchInfo.getPanId())) {
                    panInfos.add(dishInfo);
                    dishInfo.setDishInfos(new ArrayList<>());
                    continue;
                }
                //食品ID
                if (!TextUtils.isEmpty(matchInfo.getDishId())) {
                    dishInfos.add(dishInfo);
                }
            }

            List<DishInfo> inPanDishs = new ArrayList<>();
            for (DishInfo panInfo : panInfos) {
                for (DishInfo dishInfo : dishInfos) {
                    MatchLocation box1 = dishInfo.getLocation();
                    MatchLocation box2 = panInfo.getLocation();
                    double minArea = Math.min(box1.getWidth() * box1.getHeight(), box2.getWidth() * box2.getHeight());

                    double b1_x1 = box1.getLeft();
                    double b1_x2 = box1.getLeft() + box1.getWidth();
                    double b1_y1 = box1.getTop();
                    double b1_y2 = box1.getTop() + box1.getHeight();
                    double b2_x1 = box2.getLeft();
                    double b2_x2 = box2.getLeft() + box2.getWidth();
                    double b2_y1 = box2.getTop();
                    double b2_y2 = box2.getTop() + box2.getHeight();
                    double interWidth = Math.min(b1_x2, b2_x2) - Math.max(b1_x1, b2_x1);
                    double interHeight = Math.min(b1_y2, b2_y2) - Math.max(b1_y1, b2_y1);
                    double interArea = (interWidth > 0 ? interWidth : 0) * (interHeight > 0 ? interHeight : 0);

                    if (interArea / minArea > 0.6) {
                        panInfo.getDishInfos().add(dishInfo);
                        inPanDishs.add(dishInfo);
                    }
                }
            }
            showDishInfos.addAll(panInfos);
            for (DishInfo dishInfo : dishInfos) {
                if (inPanDishs.contains(dishInfo)) {
                    continue;
                }
                showDishInfos.add(dishInfo);
            }
            //endregion
        } else {
            showDishInfos = panDishInfos;
        }

//        titleMap.clear();
//        priceMap.clear();
        String border_color = recognizeSet == null || recognizeSet.getBorder_color() == null ? "#0000FF" : recognizeSet.getBorder_color();
        String font_color = recognizeSet == null || recognizeSet.getFont_color() == null ? "#FFFFFF" : recognizeSet.getFont_color();
        Pattern colorPattern = Pattern.compile("^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$");
        Matcher borderColorMatcher = colorPattern.matcher(border_color);
        Matcher fontColorMatcher = colorPattern.matcher(font_color);
        border_color = borderColorMatcher.matches() && recognizeSet != null && recognizeSet.getBorder_color() != null ? recognizeSet.getBorder_color() : "#0000FF";
        font_color = fontColorMatcher.matches() && recognizeSet != null && recognizeSet.getFont_color() != null ? recognizeSet.getFont_color() : "#FFFFFF";
        int borderColor = Color.parseColor(border_color);
        int fontColor = Color.parseColor(font_color);

        Bitmap randerBitmap = resource.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(randerBitmap);

        int border_size = recognizeSet == null || recognizeSet.getBorder_size() == 0 ? 2 : recognizeSet.getBorder_size();
        int font_size = recognizeSet == null || recognizeSet.getFont_size() == 0 ? 40 : recognizeSet.getFont_size();

        Paint borderPaint = new Paint();
        borderPaint.setColor(borderColor);
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(SlidePopupWindow.dp2px(border_size));

        Paint fontBgPaint = new Paint();
        fontBgPaint.setColor(borderColor);
        fontBgPaint.setStyle(Paint.Style.FILL);
        fontBgPaint.setAlpha(50);
        fontBgPaint.setStrokeWidth(SlidePopupWindow.dp2px(border_size));

        Paint fontPaint = new Paint();
        fontPaint.setColor(fontColor);
        fontPaint.setTextSize(font_size);

        int name_show = recognizeSet == null ? 1 : recognizeSet.getName_show();
        int price_show = recognizeSet == null ? 0 : recognizeSet.getPrice_show();
        float template_threshold = recognizeSet == null ? 0f : recognizeSet.getTemplate_threshold();
        Boolean tipLrState = false;
        for (DishInfo dishInfo : showDishInfos) {
            try {
                MatchLocation location = dishInfo.getLocation();
                LayoutInflater layoutInflater = LayoutInflater.from(mContext);
                View dishView = layoutInflater.inflate(R.layout.cover_layout, null);

                TextView cover_title = dishView.findViewById(R.id.cover_title);
                TextView cover_price = dishView.findViewById(R.id.cover_price);
                View cover_split_line = dishView.findViewById(R.id.cover_split_line);
                View cover_tip_layout = dishView.findViewById(R.id.cover_tip_layout);
                View cover_scrollview = dishView.findViewById(R.id.cover_scrollview);
                ListView cover_listview = dishView.findViewById(R.id.cover_listview);
                if (recognition_mode == 3 && dishInfo.getDishInfos() != null && dishInfo.getDishInfos().size() > 0) {
                    cover_scrollview.setVisibility(View.VISIBLE);
                    DishListAdapter dishListAdapter = new DishListAdapter(mContext, dishInfo.getDishInfos(), borderColor, fontColor, (float) (font_size / 2));
                    cover_listview.setAdapter(dishListAdapter);
                } else {
                    cover_scrollview.setVisibility(View.GONE);
                }
                GradientDrawable drawable = (GradientDrawable) getResources().getDrawable(R.drawable.cover_background);
                drawable.setStroke(SlidePopupWindow.dp2px(border_size), borderColor);
                dishView.setBackground(drawable);
                cover_tip_layout.setBackgroundColor(borderColor);
                cover_tip_layout.setAlpha(0.5f);
                cover_split_line.setBackgroundColor(borderColor);
                cover_title.setTextColor(fontColor);
                cover_price.setTextColor(fontColor);
                cover_title.setTextSize((float) (font_size / 2));
                cover_price.setTextSize((float) (font_size / 2));
                if (name_show == 1) {
                    cover_title.setVisibility(View.VISIBLE);
                } else {
                    cover_title.setVisibility(View.INVISIBLE);
                }
                if (price_show == 1) {
                    cover_price.setVisibility(View.VISIBLE);
                } else {
                    cover_price.setVisibility(View.INVISIBLE);
                }
                List<MatchInfo> matchInfos = dishInfo.getMatchInfos();

//                titleMap.put(dishInfo, cover_title);
//                priceMap.put(dishInfo, cover_price);

                int matchWidth = (int) (location.getWidth() * realWidth);
                int matchHeight = (int) (location.getHeight() * realHeight);
                int matchLeft = (int) (location.getLeft() * realWidth);
                int matchTop = (int) (location.getTop() * realHeight);

                int realmatchWidth = (int) (location.getWidth() * resource.getWidth());
                int realmatchHeight = (int) (location.getHeight() * resource.getHeight());
                int realmatchLeft = (int) (location.getLeft() * resource.getWidth());
                int realmatchTop = (int) (location.getTop() * resource.getHeight());

                MatchInfo matchInfo = findMatchInfo(realmatchWidth, realmatchHeight, matchInfos);
                dishInfo.setHeadMatchInfo(matchInfo);

                String matchName = TextUtils.isEmpty(matchInfo.getDishName()) ? matchInfo.getPanName() : matchInfo.getDishName();
                boolean noIn = template_threshold > matchInfo.getSimilarity();
                matchName = noIn ? "未录入/未排菜" : matchName;
                cover_title.setText(matchName);

                if (!noIn) {
                    MenuPicture menuPicture = null;
                    if (!TextUtils.isEmpty(matchInfo.getDishId())) {
                        menuPicture = fillCollection(dishInfo, Integer.parseInt(matchInfo.getDishId()));
                    } else if (!TextUtils.isEmpty(matchInfo.getPanId())) {
                        menuPicture = fillCollection(dishInfo, Integer.parseInt(matchInfo.getPanId()));
                    }
                    if (menuPicture != null) {
//                        cover_price.setText(ConsumeUtils.moneyFormat(countMenuMoney(mConsumptionType, menuPicture)) + "元");
                    }
                } else {
                    tipLrState = true;
                }
                Log.e(TAG, "matchLeft:" + matchLeft + ",matchTop:" + matchTop + ",matchWidth:" + matchWidth + ",matchHeight:" + matchHeight);
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(matchWidth, matchHeight);
                params.leftMargin = matchLeft;
                params.topMargin = matchTop;
                dishView.setLayoutParams(params);
                rander_layout.addView(dishView);

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                Log.e(TAG, "realmatchLeft:" + realmatchLeft + ",realmatchTop:" + realmatchTop + ",realmatchWidth:" + realmatchWidth + ",realmatchHeight:" + realmatchHeight);
                Bitmap locationBitmap = Bitmap.createBitmap(resource, realmatchLeft, realmatchTop, realmatchWidth, realmatchHeight);
                locationBitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos);
                byte[] bytes = baos.toByteArray();
                dishInfo.setSubImage(bytes);
//                dishView.setOnClickListener((view) -> {
//                    if (products == null) return;
//                    FragmentManager fragmentManager = getSupportFragmentManager();
//                    Bundle bundle = new Bundle();
//                    bundle.putParcelableArrayList(RecognizeDialogFragment.MATCHINFOS, (ArrayList<? extends Parcelable>) matchInfos);
//                    bundle.putParcelableArrayList(MenuAddDialogFragment.PRODUCTS, (ArrayList<? extends Parcelable>) products);
//                    bundle.putByteArray(RecognizeDialogFragment.PICTUREURL, bytes);
//                    bundle.putParcelable(MENUPICTURE, dishInfo.getMenuPicture());
//                    bundle.putParcelable(CONSUMPTIONTYPE, mConsumptionType);
//                    bundle.putParcelableArrayList(ENABLEMENUS, (ArrayList<? extends Parcelable>) enableMenus);
//                    bundle.putParcelable(DISHINFO, dishInfo);
//                    RecognizeDialogFragment recognizeDialogFragment = new RecognizeDialogFragment();
//                    recognizeDialogFragment.setArguments(bundle);
//                    recognizeDialogFragment.show(fragmentManager, RecognizeDialogFragment.class.getSimpleName());
//                });
                float left = location.getLeft() * randerBitmap.getWidth();
                float top = location.getTop() * randerBitmap.getHeight();
                float right = left + location.getWidth() * randerBitmap.getWidth();
                float bottom = top + location.getHeight() * randerBitmap.getHeight();
                canvas.drawRect(left, top, right, bottom, borderPaint);
                canvas.drawRect(left, top, right, top + font_size + 10, fontBgPaint);
                canvas.drawText(matchName/* + (floatPrice == 0 ? "" : "|" + floatPrice + "元")*/, left + 5, top + font_size + 5, fontPaint);
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
        if (tipLrState) {
//            msgTip("存在未录入或未排菜,请注意",2);
        }
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            randerBitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos);
//            setMenuIDPicture(Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT));
            randerBitmap.recycle();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }

//        if (differentDislay != null) {
//            differentDislay.renderShow();
//            differentDislay.updateRender(recognizeSet, showDishInfos, data, cameraInit);
//        }
//
//        if (lockMenuPicture != null) {
//            billMenuPictures.add(lockMenuPicture);
//            billMenuPicturesCount.add(1);
//        }
//        updatePayList();
    }


    class DishListAdapter extends BaseAdapter {
        private final Context mContext;
        private final int borderColor;
        private final int fontColor;
        private final float font_size;

        List<DishInfo> dishInfos;

        public DishListAdapter(Context context, List<DishInfo> dishInfos, int borderColor, int fontColor, float font_size) {
            mContext = context;
            this.dishInfos = dishInfos;
            this.borderColor = borderColor;
            this.fontColor = fontColor;
            this.font_size = font_size;
        }

        @Override
        public int getCount() {
            return dishInfos.size();
        }

        @Override
        public Object getItem(int position) {
            return dishInfos.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;

            if (convertView != null && convertView.getTag() != null) {
                holder = (ViewHolder) convertView.getTag();
            } else {
                convertView = View.inflate(mContext, R.layout.dish_item_layout, null);
                holder = new ViewHolder(convertView);
                convertView.setTag(holder);
            }

            convertView.setBackgroundColor(borderColor);
            convertView.setAlpha(0.5f);

            DishInfo dishInfo = (DishInfo) getItem(position);
            List<MatchInfo> matchInfos = dishInfo.getMatchInfos();
            MatchInfo matchInfo = matchInfos.get(0);
            holder.dish_item_title.setText(matchInfo.getDishName());
            holder.dish_item_title.setTextColor(fontColor);
            holder.dish_item_title.setTextSize(font_size);

            return convertView;
        }

        class ViewHolder {
            @BindView(R.id.dish_item_title)
            TextView dish_item_title;

            public ViewHolder(View view) {
                ButterKnife.bind(this, view);
            }
        }
    }

    private Map<String, MenuPicture> enableMenusMap = new HashMap<>();

    //识别餐盘大小份
    private MatchInfo findMatchInfo(int matchWidth, int matchHeight, List<MatchInfo> matchInfos) {
        boolean amount_mode = recognizeSet == null ? false : (recognizeSet.getAmount_mode() == 1 ? true : false);
        int recognition_mode = recognizeSet == null ? 0 : recognizeSet.getRecognition_mode();
        if (amount_mode && recognition_mode == 1) {
            for (MatchInfo matchInfo : matchInfos) {
                String panId = matchInfo.getPanId();
                if (panId == null) {
                    continue;
                }
                MenuPicture menuPicture = enableMenusMap.get(panId);
                if (menuPicture == null) continue;
                List<PictureSize> pictureSizes = menuPicture.getPictureSizes();
                for (PictureSize pictureSize : pictureSizes) {
                    float min = Math.min(matchWidth, pictureSize.getWidth());
                    float v = Math.abs(matchWidth - pictureSize.getWidth()) / min;
                    if (v < 0.1) {
                        int indexOf = matchInfos.indexOf(matchInfo);
                        matchInfos.remove(indexOf);
                        matchInfos.add(0, matchInfo);
                        return matchInfo;
                    }

                    min = Math.min(matchHeight, pictureSize.getHeight());
                    v = Math.abs(matchHeight - pictureSize.getHeight()) / min;
                    if (v < 0.1) {
                        int indexOf = matchInfos.indexOf(matchInfo);
                        matchInfos.remove(indexOf);
                        matchInfos.add(0, matchInfo);
                        return matchInfo;
                    }

                }
            }
        }
        return matchInfos.get(0);
    }

    List<MenuPicture> enableMenus = new ArrayList<>();
    protected List<MenuPicture> billMenuPictures = new ArrayList<>();
    protected List<Integer> billMenuPicturesCount = new ArrayList<>();

    @RequiresApi(api = Build.VERSION_CODES.O)
    private MenuPicture fillCollection(DishInfo dishInfo, int menuPk) {
        MenuPicture enableMenu = findProductByMenuPk(enableMenus, menuPk);
        if (enableMenu == null) return null;
//        enableMenu = (MenuPicture) enableMenu.clone();
//        billMenuPictures.add(enableMenu);
        billMenuPicturesCount.add(1);
        enableMenu.setDishInfo(dishInfo);
        dishInfo.setMenuPicture(enableMenu);
        return enableMenu;
    }

    public static MenuPicture findProductByMenuPk(List<MenuPicture> findMenus, int MenuPk) {
        for (MenuPicture findMenu : findMenus) {
            if (findMenu.getMenuPK() == MenuPk) {
                return findMenu;
            }
        }
        return null;
    }

    public void removeRander300() {

        billMenuPicturesCount.clear();
        billMenuPictures.clear();
        rander_imageview.setVisibility(View.GONE);
        rander_layout.setVisibility(View.GONE);


    }


}
